# @Time : 2024-11-06 16:56
# @Author : Fioman 
# @Phone : 13149920693
"""
什么情况下该用线程池:
1) 当你需要重复的执行多个生存期比较短暂的任务的时候,你就需要使用线程池. 为什么呢? 因为这样效率和资源
利用率比较高,为什么线程池可以做到这些呢? 因为在使用线程池的时候,不需要创建新的线程,线程池里面会维护
好固定的线程个数的线程,如果你有一个任务需要执行,就丢给线程池,如果线程池有空闲线程,这空闲线程就会去
执行这个任务,如果没有空闲线程,就会一直等待,直到有空闲线程为止.
2) 当你需要在主线程中可以获取某个线程的状态的时候,或者你需要在某个线程执行完毕之后获取其返回值的时候
你也需要使用线程池,普通的多线程无法实现这些功能
"""
import threading
import time
from concurrent.futures import ThreadPoolExecutor

"""
线程池使用步骤:
1) 使用ThreadPoolExecutor 创建线程池
2) Executor提供了如下几个方法
submit(fn,*args,**kwargs): 将函数fn提交给线程池.
map(fun,*iterables,timeout=None,chunksize=1) 启动多个线程,异步的对iterables进行map处理
shutdown(wait=True): 关闭线程池
"""

"""
程序将task函数提交submit提交给线程之后,submit方法返回一个Future对象,Future类主要用于获取线程任务
函数的返回值.由于线程任务会在新线程中以异步方式执行,因此线程执行的函数相当于是一个"将来完成"的任务,
所以Python使用Future来代表.Future提供了如下的方法:
cancel(): 取消该 Future 代表的线程任务。如果该任务正在执行，不可取消，则该方法返回 False；否则，
                程序会取消该任务，并返回 True。
cancelled(): 返回 Future 代表的线程任务是否被成功取消。
running(): 如果该 Future 代表的线程任务正在执行、不可被取消，该方法返回 True。
done(): 如果该 Funture 代表的线程任务被成功取消或执行完成，则该方法返回 True。
result(timeout=None): 获取该 Future 代表的线程任务最后返回的结果。如果 Future 代表的线程任务还未完成，
                                         该方法将会阻塞当前线程，其中 timeout 参数指定最多阻塞多少秒。
execption(timeout=None): 获取该 Future 代表的线程任务所引发的异常。如果该任务成功完成，
                                                没有异常，则该方法返回 None。
add_one_callback(fn): 为该 Future 代表的线程任务注册一个“回调函数”，当该任务成功完成时，
                                        程序会自动触发该 fn 函数。
"""

"""
在用完一个线程池后，应该调用该线程池的 shutdown() 方法，该方法将启动线程池的关闭序列。
调用 shutdown() 方法后的线程池不再接收新任务，但会将以前所有的已提交任务执行完成。
当线程池中的所有任务都执行完成后，该线程池中的所有线程都会死亡。

"""


def sleep_some_times(seconds):
    print(f"{threading.current_thread().name} 开始执行,执行耗时:{seconds} 秒")
    time.sleep(seconds)
    print(f"{threading.current_thread().name} 执行完毕")
    return f"{threading.current_thread().name} 返回结果: {seconds}"


def show_result(future):
    print(future.result())


if __name__ == '__main__':
    threadPool = ThreadPoolExecutor(max_workers=4, thread_name_prefix='sleepThread_')
    for i in range(10):
        future = threadPool.submit(sleep_some_times, i)
        future.add_done_callback(show_result)  # 执行完毕之后的回调函数

    threadPool.shutdown()
    print("主线程执行完成")
